feat(symbols): derive the upload endpoint from --base-uri - #773
Conversation
Uploading to any instance other than production took two flags that had to agree: --base-uri to name the instance, and --backend-url to name that same instance's observability API. The second is derivable from the first, since every instance publishes the API under a host named for it, which is how the production default was already built. --backend-url now defaults to the API of whichever instance --base-uri names, so staging is one flag. Only LaunchDarkly's own hosts are derived from: a base URI aimed at a local stack says nothing about where its observability API listens, so those keep the production default and --backend-url still overrides. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 1dec099. Configure here.
|
|
||
| if backendUrl == "" { | ||
| backendUrl = defaultBackendUrl | ||
| backendUrl = defaultBackendURLFor(viper.GetString(cliflags.BaseURIFlag)) |
There was a problem hiding this comment.
Silent backend default change
Medium Severity
When --backend-url is unset, uploads now derive the observability endpoint from --base-uri for LaunchDarkly hosts, changing the previous production default for non-prod instances with no transitional stderr notice. That violates the rule that user-facing CLI default changes need a warning for at least one release cycle.
Additional Locations (1)
Triggered by learned rule: Breaking CLI default changes require transitional stderr warnings
Reviewed by Cursor Bugbot for commit 1dec099. Configure here.
defaultBackendURLFor landed inside getSymbolUploadUrls' doc comment, which left that function undocumented and opened the new one with three paragraphs about upload URLs and dedup retries. Co-authored-by: Cursor <cursoragent@cursor.com>


Summary
Uploading symbols to anything other than production took two flags that had to agree:
--base-urito name the instance, and--backend-urlto name that same instance's observability API. Staging looked like this:The second flag is derivable from the first. Every instance publishes its observability API under a host named for the instance, which is exactly how the production default in this file was already built, so
--backend-urlnow defaults to the API of whichever instance--base-urinames and the command above loses a line.Only LaunchDarkly's own hosts are derived from. A base URI aimed at a local stack or a proxy says nothing about where its observability API listens, so those keep today's production default, and
--backend-urlstill overrides everything — which is how local development already points athttp://localhost:8082/private.Behavior for the default base URI is unchanged:
app.launchdarkly.comderives the samepri.observability.app.launchdarkly.comthe constant held. The flag's registered default moves from that constant to empty so the derivation can run;--helpnow names the production URL in the description instead.Test plan
go test ./cmd/symbols/— newTestDefaultBackendURLForcovers production, staging, a regional host, trailing slashes and whitespace, and the cases that fall back to the default (local stack, a host that merely ends in the domain name, unset, unparseable)go build ./...--base-uri https://ld-stg.launchdarkly.com. A staging access token authenticated, which it could not have against the production default, so the derivation reached the staging API. The mapping was keyed by thepg_map_idR8 recorded and the dedup handshake reported the index already stored there, so the handshake round-tripped but the object PUT did not re-runMade with Cursor